home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue43 / tooltips / HintGrid.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-01-25  |  4.8 KB  |  180 lines

  1. unit HintGrid;
  2. {$ifdef Ver80} { Delphi 1.0x }
  3.   {$define DelphiLessThan3}
  4. {$endif}
  5. {$ifdef Ver90} { Delphi 2.0x }
  6.   {$define DelphiLessThan3}
  7. {$endif}
  8. {$ifdef Ver93} { C++ Builder 1.0x }
  9.   {$define DelphiLessThan3}
  10. {$endif}
  11.  
  12. interface
  13.  
  14. uses
  15.   WinProcs, WinTypes, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  16.   Dialogs, Grids;
  17.  
  18. type
  19.   THintStringGrid = class(TStringGrid)
  20.   private
  21.     FHintWnd: THintWindow;
  22.   protected
  23.     function CalcHintRect(MaxWidth: Integer;
  24.       const AHint: string; HintWnd: THintWindow): TRect;
  25.     procedure DoHint(X, Y: Integer);
  26.   public
  27.     procedure CMMouseEnter(var Msg: TMessage); message cm_MouseEnter;
  28.     procedure CMMouseLeave(var Msg: TMessage); message cm_MouseLeave;
  29.     procedure WMMouseMove(var Msg: TWMMouseMove); message wm_MouseMove;
  30.   end;
  31.  
  32. {$ifdef DelphiLessThan3}
  33.   { The hint window in Delphi 1 and 2 would beep if you clicked it }
  34.   { These modifications fix that }
  35.   TCustomHint = class(THintWindow)
  36.   private
  37.     procedure WMNCHitTest(var Msg: TWMNCHitTest);
  38.       message wm_NCHitTest;
  39.   protected
  40.     procedure CreateParams(var Params: TCreateParams); override;
  41.   end;
  42.  
  43. { The private routine Forms.ForegroundTask was only made }
  44. { available in Delphi 3. This is a cheap'n'nasty version of it }
  45. function ForegroundTask: Boolean;
  46. {$endif}
  47.  
  48. procedure Register;
  49.  
  50. implementation
  51.  
  52. procedure Register;
  53. begin
  54.   RegisterComponents('Clinic', [THintStringGrid]);
  55. end;
  56.  
  57. {$ifdef DelphiLessThan3}
  58. { The private routine Forms.ForegroundTask was only made }
  59. { available in Delphi 3. This is a cheap'n'nasty version of it }
  60. function ForegroundTask: Boolean;
  61. begin
  62.   Result := FindControl(GetActiveWindow) <> nil
  63. end;
  64. {$endif}
  65.  
  66. { THintStringGrid }
  67.  
  68. function THintStringGrid.CalcHintRect(MaxWidth: Integer;
  69.   const AHint: string; HintWnd: THintWindow): TRect;
  70. {$ifdef DelphiLessThan3}
  71. var
  72.   Buf: array[0..511] of Char;
  73. begin
  74.   Result := Rect(0, 0, MaxWidth, 0);
  75.   { Ask Windows to do the hard calculation work }
  76.   DrawText(HintWnd.Canvas.Handle, StrPCopy(Buf, AHint), -1, Result,
  77.     DT_CALCRECT or DT_LEFT or DT_WORDBREAK or DT_NOPREFIX);
  78.   { Add some breathing room }
  79.   Inc(Result.Right, 6);
  80.   Inc(Result.Bottom, 2);
  81. {$else}
  82. begin
  83.   { Delphi 3+ makes this method available }
  84.   Result := HintWnd.CalcHintRect(Screen.Width, AHint, nil)
  85. {$endif}
  86. end;
  87.  
  88. procedure THintStringGrid.CMMouseEnter(var Msg: TMessage);
  89. var
  90.   Pt: TPoint;
  91. begin
  92.   GetCursorPos(Pt);
  93.   Pt := ScreenToClient(Pt);
  94.   DoHint(Pt.X, Pt.Y)
  95. end;
  96.  
  97. procedure THintStringGrid.CMMouseLeave(var Msg: TMessage);
  98. begin
  99.   inherited;
  100.   { Could destroy it, but this takes less time }
  101.   if Assigned(FHintWnd) then
  102.     FHintWnd.ReleaseHandle;
  103. end;
  104.  
  105. procedure THintStringGrid.DoHint(X, Y: Integer);
  106. const
  107.   TextOffset = 2;
  108. var
  109.   Col, Row: Longint;
  110.   R, OldR: TRect;
  111.   Pt: TPoint;
  112. begin
  113.   { Check cell under mouse }
  114.   MouseToCell(X, Y, Col, Row);
  115.   { If it is a cell, and text is bigger than screen space, }
  116.   { and in-place editor not present, and not at design-time }
  117.   Canvas.Font := Font;
  118.   if (Col <> -1) and (Row <> -1) and
  119.      (Canvas.TextWidth(Cells[Col, Row]) + TextOffset > ColWidths[Col]) and
  120.      not EditorMode and ForegroundTask and not (csDesigning in ComponentState) then
  121.   begin
  122.     { Make sure hint window exists }
  123.     if not Assigned(FHintWnd) then
  124.     begin
  125.       FHintWnd := HintWindowClass.Create(Self);
  126.       FHintWnd.Color := Application.HintColor;
  127.     end;
  128.     { Set hint text }
  129.     Hint := Cells[Col, Row];
  130.     { Calculate rect size }
  131.     R := CalcHintRect(Screen.Width, Hint, FHintWnd);
  132.     { Find target location }
  133.     Pt := ClientToScreen(CellRect(Col, Row).TopLeft);
  134.     { Tweak position so it is the same as the grid cell (hopefully) }
  135.   {$ifdef DelphiLessThan3}
  136.     Inc(Pt.Y);
  137.   {$else}
  138.     Dec(Pt.X);
  139.     Dec(Pt.Y);
  140.   {$endif}
  141.     OffsetRect(R, Pt.X, Pt.Y);
  142.     { Only draw it if it has moved - compare top-left }
  143.     { (could compare whole rect but the hint sometimes grows itself) }
  144.     GetWindowRect(FHintWnd.Handle, OldR);
  145.     if not IsWindowVisible(FHintWnd.Handle) or
  146.        not ((R.Left = OldR.Left) and (R.Top = OldR.Top)) then
  147.       FHintWnd.ActivateHint(R, Hint)
  148.   end
  149.   else
  150.     if Assigned(FHintWnd) then
  151.       FHintWnd.ReleaseHandle;
  152. end;
  153.  
  154. procedure THintStringGrid.WMMouseMove(var Msg: TWMMouseMove);
  155. begin
  156.   inherited;
  157.   DoHint(Msg.XPos, Msg.YPos)
  158. end;
  159.  
  160. {$ifdef DelphiLessThan3}
  161. { TCustomHint }
  162.  
  163. procedure TCustomHint.CreateParams(var Params: TCreateParams);
  164. begin
  165.   inherited CreateParams(Params);
  166.   Params.Style := Params.Style and not ws_Disabled;
  167. end;
  168.  
  169. procedure TCustomHint.WMNCHitTest(var Msg: TWMNCHitTest);
  170. begin
  171.   Msg.Result := HTTRANSPARENT;
  172. end;
  173.  
  174. initialization
  175.   Application.ShowHint := not Application.ShowHint;
  176.   HintWindowClass := TCustomHint;
  177.   Application.ShowHint := not Application.ShowHint;
  178. {$endif}
  179. end.
  180.